import UIKit

/**
    B站：https://www.bilibili.com/video/BV144411C7Gg?p=44

    第44课
        1. 闭包循环引用
        2. 定义捕获列表  unowned(无主引用) / weak(可能会没有值)

 */

class Test {
    var name: String = ""
    // 闭包 (用到self，当我初始化 self 可能还没有初始化完成，就使用 self 会有问题 需要用 lazy)
    lazy var data: () -> Void = {() -> Void in
//        print("self(当前实例的应用).name=") // 闭包不循环引用
        print("Test self(当前实例的应用).name=", self.name) // 闭包循环应用
    }
    
    init(name: String) {
        self.name = name
    }
    
    deinit {
        print("Test 被释放了")
    }
}

var t : Test? = Test(name: "hhhello")
t!.data()

t = nil
// 执行后，并没有 释放 引用(引用没有减一)


// ------------------------------------------------------------------------------
// ------ 捕获列表 unowned(无主引用) / weak(可能会没有值)
// 解决
// 1. 闭包 unowned
class Test22 {
    var name: String = ""
    lazy var data: () -> Void = {[unowned self]() in
//        print("self(当前实例的应用).name=") // 闭包不循环引用
        print("Test22 self(当前实例的应用).name=", self.name) // 闭包循环应用
    }
    
    init(name: String) {
        self.name = name
    }
    
    deinit {
        print("Test22 被释放了")
    }
}

var t2 : Test22? = Test22(name: "wworld")
t2!.data()
t2 = nil


// 2. 闭包 weak
class Test33 {
    var name: String = ""
    lazy var data: () -> Void = {[weak self] in
//        print("self(当前实例的应用).name=") // 闭包不循环引用
        print("Test33 self(当前实例的应用).name=", self?.name ?? "unknow.name") // 闭包循环应用
    }
    
    init(name: String) {
        self.name = name
    }
    
    deinit {
        print("Test33 被释放了")
    }
}

var t3 : Test33? = Test33(name: "wworld")
t3!.data()
t3 = nil
